﻿using SocketUDPAndTCPcommunication.ServerResponse;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SocketUDPAndTCPcommunication
{
    class TCPProgrammeServer
    {
        private string IP;
        private int Port;
        private int MaxListenCount = 1;

        private Socket serverSocket; // 服务端通讯主机socket
        private byte[] readBuff;
        public TCPProgrammeServer(string _IP, int _Port)
        {
            IP = _IP;
            Port = _Port;
        }

        public void ConnectByTCP()
        {
            Console.WriteLine("开始尝试TCP异步监听");
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(IP), Port);
            serverSocket.Bind(endPoint); 
            serverSocket.Listen(MaxListenCount);
            serverSocket.BeginAccept(OnAccept, serverSocket); 
        }

        private void OnAccept(IAsyncResult ar)
        { // 结束挂起回调此方法
            Console.WriteLine("接收到消息处理");
            Socket newScoket = serverSocket.EndAccept(ar);
            readBuff = new byte[1024];                    ///这里只让一个readbuff接收数据可能会引起错误（多个协程访问一个readbuff）
            newScoket.BeginReceive
                (
                readBuff,
                0, readBuff.Length,
                SocketFlags.None,
                TCPOnBeginReceiveCllback,
                newScoket
                );
            //等待连接
            serverSocket.BeginAccept(OnAccept, serverSocket);
        }

        private void TCPOnBeginReceiveCllback(IAsyncResult asyncResult)
        {
            Console.WriteLine("接收到消息处理");
            Socket mainSocket = asyncResult.AsyncState as Socket;
            int msgCount = mainSocket.EndReceive(asyncResult);//结束挂起接收

            //处理操作
            NetworkServerProtocolManage networkServerProtocolManage = new NetworkServerProtocolManage();
            if (!networkServerProtocolManage.ResponseProtocol(readBuff,msgCount))
                return;

            readBuff = new byte[1024];
            mainSocket.BeginReceive(
            readBuff, // 消息缓存
            0, readBuff.Length, // 消息接收的起始点以及长度
            SocketFlags.None, // 标志
            TCPOnBeginReceiveCllback, // 接收到消息的回调
            mainSocket // 状态
            );
        }
    }
}
